package net.ericaro.neojavagengen;

import net.ericaro.neojavagen.Literals;
import net.ericaro.neojavagen.packages.CompilationUnit;
import net.ericaro.neojavagen.packages.ImportDeclaration;
import net.ericaro.neojavagen.packages.ImportDeclarations;
import net.ericaro.neojavagen.packages.PackageDeclaration;
import net.ericaro.neojavagen.packages.TypeDeclaration;
import net.ericaro.neojavagen.packages.TypeDeclarations;


public abstract class Meta {
	
	
	MetaType self;
	Grammar grammar;
	
	protected CompilationUnit compilationUnit;
	private ImportDeclarations importDeclarations;
	
	public Meta(Grammar grammar,String name) {
		super();
		this.self = grammar.createMetaType(name);
		self.setPackageName(Literals.identifier(grammar.currentPackage.toLowerCase()));
		
		self.attach(this);
		this.grammar = grammar;
	}
	
	
	public MetaType getMetaType(){return self;}
	
	
	public CompilationUnit getCompilationUnit(){
		if (compilationUnit == null ){
			createCompilationUnit();
		}
		return compilationUnit;
	}
	
	
	
	
	private void createCompilationUnit(){
		importDeclarations = new ImportDeclarations();// keep import for later use
		// creates a compilation unit with a single type decl, as defined by sub classes
		compilationUnit = new CompilationUnit(new PackageDeclaration(getMetaType().getQualifiedPackageName()), importDeclarations, new TypeDeclarations(getTypeDeclaration()));
		
		
		
		
	}

	/** used to append import from sub classes
	 * 
	 * @param importDeclaration
	 */
	protected void addImportDeclaration(ImportDeclaration importDeclaration){
		importDeclarations.add(importDeclaration);
	}
	
	/** implemented by subclasses to create the type declaration
	 * 
	 * @return
	 */
	protected abstract TypeDeclaration getTypeDeclaration() ;
	
}
